use concurrency::CmapMetrics;
use rand::Rng;
use std::{thread, time::Duration};

const TASK_WORKER_NUM: usize = 2;
const REQ_WORKER_NUM: usize = 4;

fn main() -> anyhow::Result<()> {
    let metrics = CmapMetrics::new();

    // start N works and M requests;
    for index in 0..TASK_WORKER_NUM {
        task_worker(index, metrics.clone())?;
    }

    for _ in 0..REQ_WORKER_NUM {
        request_worker(CmapMetrics {
            data: std::sync::Arc::clone(&metrics.data),
        })?;
    }

    loop {
        thread::sleep(Duration::from_secs(5));
        // println!("{:?}", metrics.snapshot());
        println!("{}", metrics);
    }
}

fn task_worker(index: usize, metrics: CmapMetrics) -> anyhow::Result<()> {
    thread::spawn(move || loop {
        // do long term stuff
        let mut rng = rand::thread_rng();
        thread::sleep(Duration::from_millis(rng.gen_range(100..5000)));
        let _ = metrics.inc(format!("call.thread.worker.{}", index));
    });
    Ok(())
}

fn request_worker(metrics: CmapMetrics) -> anyhow::Result<()> {
    thread::spawn(move || loop {
        // process requests
        let mut rng = rand::thread_rng();
        thread::sleep(Duration::from_millis(rng.gen_range(50..800)));
        let page = rng.gen_range(1..5);
        let _ = metrics.inc(format!("req.page.{}", page));
    });
    Ok(())
}
